package machineLearning.featurecalculator;

import java.lang.reflect.Array;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import rainbownlp.analyzer.sentenceclause.SentenceClauseManager;
import rainbownlp.core.Artifact;
import rainbownlp.core.FeatureValuePair;
import rainbownlp.core.FeatureValuePair.FeatureName;
import rainbownlp.machineLearning.IFeatureCalculator;
import rainbownlp.machineLearning.MLExample;
import rainbownlp.machineLearning.MLExampleFeature;
import rainbownlp.parser.DependencyLine;
import rainbownlp.util.StanfordDependencyUtil;
import rainbownlp.util.StringUtil;
import sentimentanalysis.databases.NRCEmotionLexiconTable;
import sentimentanalysis.databases.WordnetManager;
import sentimentanalysis.databases.WordnetSynset;



public class NRCEmotionInclusiveFeatures implements IFeatureCalculator {

	
	/*
	 * Count how many previous same type artifact exists
	 */
	public static HashMap<String, ArrayList<String>> word_emotions = new HashMap<String, ArrayList<String>>();
	public static HashMap<String,ArrayList<String>> sent_nrc_dep_map = new HashMap<String, ArrayList<String>>();
	public static void main(String[] args) throws Exception
	{
		List<MLExample> trainExamples = 
			MLExample.getAllExamples(true);
		int count =0;
		for(MLExample example_to_process: trainExamples)
		{
			NRCEmotionInclusiveFeatures nrc =  new NRCEmotionInclusiveFeatures();
			
			
			nrc.calculateFeatures(example_to_process);
			count++;
			System.out.println("************* "+count+"/"+trainExamples.size());
			
		}	
		count =0;
		List<MLExample> testExamples = 
			MLExample.getAllExamples(false);

		for(MLExample example_to_process: testExamples)
		{
			NRCEmotionInclusiveFeatures nrc =  new NRCEmotionInclusiveFeatures();
			
			
			nrc.calculateFeatures(example_to_process);
			count++;
			System.out.println("************* "+count+"/"+testExamples.size());
		}
		
	}
	
	@Override
	public void calculateFeatures (MLExample exampleToProcess) throws SQLException {
		Artifact sentence = exampleToProcess.getRelatedArtifact();
		
		ArrayList<String> NRC_nor_deps= sent_nrc_dep_map.get(sentence.getAssociatedFilePath());
		if(NRC_nor_deps ==null)
		{
			NRC_nor_deps = new ArrayList<String>();
			ArrayList<DependencyLine> dependencies= 
				StanfordDependencyUtil.parseDepLinesFromString(sentence.getStanDependency());
		
		
			for (DependencyLine dependency : dependencies) {
				
				
				String NRC_nor_dep = dependency.relationName;
				ArrayList<String> first_included_emotions = new ArrayList<String>();
				
				first_included_emotions = getAssociatedEmotions
						(word_emotions, dependency.firstPart, dependency.firstOffset, sentence,"wordnet",null);
	
				
				ArrayList<String> second_included_emotions = new ArrayList<String>();
				second_included_emotions  = getAssociatedEmotions
				(word_emotions, dependency.secondPart, dependency.secondOffset, sentence,"wordnet",null);
				
//				first_included_emotions.add(StringUtil.getTermByTermWordnet(dependency.firstPart));
//				second_included_emotions.add(StringUtil.getTermByTermWordnet(dependency.secondPart));
				
				for (String first_included:first_included_emotions)
					for(String second_emotion: second_included_emotions)
					{
						String new_extended = NRC_nor_dep+"_"+first_included+"_"+second_emotion;
						if (!NRC_nor_deps.contains(new_extended))
							NRC_nor_deps.add(new_extended);
	//					System.out.println(NRC_nor_dep+"_"+first_included+"_"+second_emotion);	
					}
			}
			sent_nrc_dep_map.put(sentence.getAssociatedFilePath(),NRC_nor_deps);
		}
			////////////////////
		for (String nor_dep: NRC_nor_deps)
		{
			FeatureValuePair NRC_dep_sent = 
				FeatureValuePair.getInstance
				(FeatureName.NRCDependenciesInclusive, nor_dep,"1");
			MLExampleFeature.setFeatureExample(exampleToProcess, NRC_dep_sent);	
		}
		
		
	}
	

	public static ArrayList<String> neg_NRC_emotions = new ArrayList<String>
		(Arrays.asList("anger","disgust","fear","sadness"));
	
	public static ArrayList<String> pos_NRC_emotions = new ArrayList<String>
	(Arrays.asList("joy","surprise","trust"));
	//this method tries to find the list of emotions from National research council canada
	public static ArrayList<String> getAssociatedEmotions
	(HashMap<String, ArrayList<String>> emotions,String word,
			Integer offset, Artifact sentence,
			String generalizationOption, String polariyOrEmotion) throws SQLException
			{
		
		ArrayList<String> included_emotions = emotions.get(word+"_"+offset);
		
		if(included_emotions== null)
		{
			included_emotions = new ArrayList<String>();
			Artifact word_artifact = sentence.getChildByWordIndex(offset-1);
			if (word_artifact == null)
				return included_emotions;
			String pos = word_artifact.getPOS();
			
			Integer pol = NRCEmotionLexiconTable.getNRCPolarity(word);
			
			included_emotions =
				NRCEmotionLexiconTable.
					getAssociatedNRCEmotions(StringUtil.getTermByTermWordnet(word));
			boolean has_neg= false;
			boolean has_pos = false;
			
			//handling conflicting emotions
			if(included_emotions.size()>1)
			{
				for(String emotion:included_emotions)
				{
					if(has_neg ==false && neg_NRC_emotions.contains(emotion))
					{
						has_neg=true;
					}
					if(has_pos==false && pos_NRC_emotions.contains(emotion))
					{
						has_pos=true;
					}
				}
				//here is the conflict
				if ((pol != null && pol>0 && has_neg) || (pol != null && pol<0 && has_pos))
				{
					included_emotions=new ArrayList<String>();
				}
			
			}
			

		
//			if (generalizationOption.equals("wordnet"))
//			{
//				String wordnet_represemntative = WordnetSynset.selectOrCreateSynsetRepresentative(word, pos);
//				included_emotions.add(wordnet_represemntative);
//			}
			
			// If there is no emotion get polarity
			if (included_emotions.isEmpty())
			{
//					Integer pol = NRCEmotionLexiconTable.getPolarity(word, pos);
				if (pol != null && pol>0)
				{
					included_emotions.add("positive");
				}
				else if (pol != null && pol<0)
				{
					included_emotions.add("negative");
				}
			}
//			if (included_emotions.isEmpty())
//			{
//				included_emotions.add(word);
//			}
			included_emotions.add(word);
			emotions.put(word+"_"+offset,included_emotions);
		}
		return included_emotions;
	}
	public static ArrayList<String> getJustAssociatedEmotions(HashMap<String, ArrayList<String>> emotions,String word, Integer offset,
			Artifact sentence)
	{
		
		ArrayList<String> included_emotions = emotions.get(word+"_"+offset);
		
		if(included_emotions== null)
		{
			Artifact word_art = sentence.getChildByWordIndex(offset-1);
			String pos =  word_art.getPOS();
//			Integer pol = NRCEmotionLexiconTable.getPolarity(word, pos);
			
			included_emotions =
				NRCEmotionLexiconTable.
				getAssociatedNRCEmotions(StringUtil.getTermByTermWordnet(word));
			
			emotions.put(word+"_"+offset,included_emotions);
		}
		
		return included_emotions;
	}

	public static ArrayList<String> getSentNRCNormalizedDep(Artifact sent,String gen_optio, String polarity_option) throws Exception
	{
		ArrayList<String> NRC_nor_lines = new ArrayList<String>();
		
		ArrayList<DependencyLine> dependencies= StanfordDependencyUtil.parseDepLinesFromString(sent.getStanDependency());
		HashMap<String, ArrayList<String>> word_emotions = new HashMap<String, ArrayList<String>>();
		
		for (DependencyLine dependency : dependencies) {
			
			
			String NRC_nor_dep = dependency.relationName;
			
			ArrayList<String> first_included_emotions = getAssociatedEmotions
					(word_emotions, dependency.firstPart, dependency.firstOffset, sent,gen_optio,polarity_option);
//			ArrayList<String> first_included_emotions = getAssociatedEmotions
//					(word_emotions, dependency.firstPart, dependency.firstOffset, sent,"pos_if_empty","org_for_polar");
			

			//"pos_if_empty","just_pol"
			ArrayList<String> second_included_emotions = getAssociatedEmotions
					(word_emotions, dependency.secondPart, dependency.secondOffset, sent,gen_optio,polarity_option);
//			ArrayList<String> second_included_emotions = getAssociatedEmotions
//					(word_emotions, dependency.secondPart, dependency.secondOffset, sent,"pos_if_empty","org_for_polar");
			
			
			for (String first_included:first_included_emotions)
				for(String second_emotion: second_included_emotions)
				{
					NRC_nor_lines.add(NRC_nor_dep+"_"+first_included+"_"+second_emotion);
				}
			
		}
	
		return NRC_nor_lines;
		
	}
	public static String getSentNRCNormalizedDepString(Artifact sent,String gen_optio, String polarity_option) throws Exception
	{
		String NRC_nor_dep_string="";
		
		ArrayList<String> nrc_deps = getSentNRCNormalizedDep(sent,gen_optio,polarity_option);
		for (String dep:nrc_deps)
		{
			NRC_nor_dep_string = NRC_nor_dep_string.concat(" "+dep);
		}
		NRC_nor_dep_string = NRC_nor_dep_string.concat("\n");
		return NRC_nor_dep_string;
	}

}